home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / pctecap.arc / DSCOPE1.ASM < prev    next >
Assembly Source File  |  1986-03-15  |  6KB  |  191 lines

  1. ;
  2. ;            Program DSCOPE1
  3. ;        copyright (C) 1983  Peter G. Aitken
  4. ;            Department of Physiology
  5. ;     Duke University Medical Center, Durham, NC 27710
  6. ;
  7. ;  This program collects and averages sweeps of analog data from
  8. ;  channel 0 of the labmaster board, with each sweep triggered
  9. ;  by a pulse on channel 7.  It requires that the calling program set
  10. ;  up clock 5 to output pulses at the desired sampling rate, and
  11. ;  that the Labmaster be jumpered for external start a/d conversions.
  12. ;  The calling program must also pass two parameters: the address of the
  13. ;  array for data storage, and the number of sweeps to be averaged.
  14. ;  Program now collects 640 points/sweep. Subroutine "beep" beeps the
  15. ;  speaker after each sweep. Maximum sampling rate=40kHz.
  16. ;
  17. sseg        segment    stack        ;set up stack.
  18.         dw    20 DUP (?)
  19. sseg        ends
  20. ;
  21. dseg        segment            ;set up data segment.
  22. array        dw (?)
  23. nswps        dw (?)
  24. dseg        ends
  25. ;
  26. cseg        segment    public 'CODE'    ;code segment.
  27. ;
  28.         assume cs:cseg,ss:sseg,ds:dseg
  29. ;
  30.         public    dscope1        ;declare "dscope1" public so it can
  31.                     ;be called from another program.
  32. dscope1        proc    far
  33.         push    bp        ;save register.
  34.         mov    bp,sp
  35.         mov    si,[bp]+8    ;get first parameter passed by
  36.                     ;calling program.
  37.         mov    dx,[si]
  38.         mov    array,dx    ;data array address in "array".
  39.         mov    si,[bp]+6    ;get second parameter passed.
  40.         mov    dx,[si]
  41.         mov    nswps,dx    ;# sweeps in nswps.
  42.         inc    nswps        ;now nswps=#sweeps+1.
  43. ;
  44. ;now we go thru the array and zero all elements.
  45. ;
  46.         mov    bx,array    ;bx points at base of array.
  47.         mov    si,0        ;si indexes array element.
  48.         mov    cx,640        ;cx counts array elements.
  49.         mov    ax,0
  50. zero_loop:    mov    [bx][si],ax    ;move "0" to array element.
  51.         add    si,2        ;point at next element.
  52.         loop    zero_loop    ;loop back if cx<>0.
  53. ;
  54. ;now we wait for a synch pulse on a/d channel 7.
  55. ;
  56. synch_loop:    nop
  57.         dec    nswps        ;nswps now = # sweeps remaining.
  58.         jz    done        ;if it's 0, we're done.
  59. ;
  60. wait_synch:    mov    dx,0714H    ;point at control byte.
  61.         mov    al,10000000B    ;disable autoincrement and
  62.         out    dx,al        ;all interrupts.
  63.         inc    dx        ;point at a/d channel byte and
  64.         mov    al,7        ;specify that next channel
  65.         out    dx,al        ;to convert is #7.
  66.         inc    dx        ;point at a/d start & hi data.
  67.         in    al,dx        ;read high data to reset
  68.                     ;done bit.
  69.         out    dx,al        ;start a conversion.
  70.         mov    dx,0714H    ;point dx at status byte
  71. wait_done:    in    al,dx        ;and read it in.
  72.         cmp    al,10000000B    ;see if bit 7 is set.
  73.         jb    wait_done     ;if not, look again.
  74.         inc    dx        ;point at low data byte.
  75.         in    ax,dx        ;read ch#7 voltage.
  76.         cmp    ax,1024        ;is it > "1024"?
  77.         jl    wait_synch    ;if not, try again.
  78. ;
  79. ;now that a synch pulse has been received, we can collect data
  80. ;
  81. get_data:    mov    cx,640        ;cx will count loops.
  82.         mov    si,0        ;si=array offset pointer.
  83.         mov    bx,array    ;bx=array base pointer.
  84.         mov    dx,0714H    ;point at control byte.
  85.         mov    al,10000100B    ;enable external starts and
  86.         out    dx,al        ;disable autoincrementing.
  87.         inc    dx        ;point dx at 0715H.
  88.         in    ax,dx        ;read data to clear "done"bit.
  89.         mov    al,0
  90.         out    dx,al        ;specify a/d channel #0.
  91. data_loop:    dec     dx        ;point at status byte
  92. in_loop:    in    al,dx        ;and get it.
  93.         cmp    al,10000000B    ;is bit 7 set?
  94.         jb    in_loop        ;no, try again.
  95.         inc    dx        ;point at 0715h.
  96.         in    ax,dx        ;get data word and
  97.         add    [bx][si],ax    ;add it to array.
  98.         add    si,2        ;point si at next array element.
  99.         loop    data_loop    ;and loop back if 640 pts haven't
  100.                     ;been collected, i.e., if cx>0.
  101.         dec    dx        ;point at control byte.
  102.         mov    al,10000000B    ;disable autostart.
  103.         out    dx,al
  104. ;
  105.         call    beep        ;beep speaker.
  106. ;
  107. ;put "x" plus 2 spaces on screen to indicate sweep.
  108. ;
  109.         push    ax        ;save registers.
  110.         push    bx
  111.         push    bp
  112.         mov    bh,0        ;select display page.
  113.         mov    al,120        ;character "x".
  114.         mov    ah,14        ;write, advance cursor.
  115.         int    10H
  116.         mov    ah,14
  117.         mov    al,32        ;character " ".
  118.         int    10H
  119.         mov    ah,14
  120.         mov    al,32        ;character " ".
  121.         int    10H
  122.         pop    bp        ;restore registers.
  123.         pop    bx
  124.         pop    ax
  125. ;
  126.         jmp    synch_loop    ;go wait for another pulse.
  127. ;
  128. done:        nop
  129. ;
  130. ;now go back thru array dividing by # sweeps.
  131. ;
  132.         mov    si,[bp]+6
  133.         mov    dx,[si]        ;now dx has # sweeps.
  134.         mov    nswps,dx    ;now nswps has # sweeps.
  135.         mov    si,0
  136.         mov    cx,640        ;cx will count loops.
  137. div_loop:    mov    ax,[bx][si]    ;move array element to ax.
  138.         cwd            ;convert to dbl word.
  139.         idiv    nswps        ;divide by # sweeps.
  140.         mov    [bx][si],ax    ;put quotient back in array.
  141.         add    si,2        ;point at next array element.
  142.         loop    div_loop    ;loop back if all not done.
  143. ;
  144.         pop    bp        ;restore bp.
  145.         sti
  146.         ret    4
  147. dscope1        endp
  148. ;
  149. ;this subroutine "beep" plays a tone on the speaker - desired duration
  150. ;(in milliseconds) and frequency (in Hz) are placed in bx
  151. ;and di, respectively.
  152. ;
  153. beep        proc
  154.         push     ax        ;save registers.
  155.         push     bx
  156.         push    cx
  157.         push    dx
  158.         push    di
  159.         mov    di,500        ;set frequency.
  160.         mov    bx,50        ;set duration to 50 msec.
  161.         mov    al,0B6H        ;write control byte to timer mode reg.
  162.         out    43H,al
  163.         mov    dx,14H        ;to get desired freq, we must send
  164.         mov    ax,4F38H    ;the value 1331000/freq to timer 2.
  165.         div    di
  166.         out    42H,al        ;write low byte to timer 2.
  167.         mov    al,ah
  168.         out    42H,al        ;write high byte to timer 2.
  169.         in    al,61H        ;get current timer port setting.
  170.         mov    ah,al        ;save it in ah.
  171.         or    al,3        ;change bits 0 and 1 and send to timer
  172.         out    61H,al        ;port, which turns speaker on.
  173. hold_it:    mov    cx,280        ;wait 1 msec.
  174. beeping:    loop    beeping        ;this loop cycles 280 times in one
  175.                     ;msec.
  176.         dec    bx        ;has the count expired?
  177.         jnz    hold_it        ;if not, go back for another msec.
  178.         mov    al,ah        ;recover port value.
  179.         out    61H,al        ;speaker off.
  180.         pop    di        ;restore reg.
  181.         pop    dx
  182.         pop    cx
  183.         pop    bx
  184.         pop    ax
  185.         ret
  186. beep        endp
  187. ;
  188. cseg        ends
  189.         end
  190. ;
  191.